#title: Dao 接口的基本操作
#index:0,1

----------------------------------------------------------------------------------------------------
概述
	传统关系型数据库定义了四种数据操作：
	 # 插入 Insert
	 # 删除 Delete
	 # 更新 Update
	 # 查询 Query
	可以说，这四种操作涵盖了所有的数据操作。并且，除了 {_插入} 操作，所有的操作都是可以一次针对多条记录的。
	
	但是，Nutz.Dao 认为从使用者的角度来看，这四种操作还是有所不同的。比如，查询返回的结果，很多时候仅仅是一条记录。
	我们需要为这种情况进行优化。所以，Nutz.Dao 在传统关系型数据库数据操作的基础上定义了如下的数据操作：
	|| 插入 || Insert	|| 一条 SQL 插入一条记录或者多条记录 ||
	|| 插入 || FastInsert|| 一条 SQL ,通过batch插入多条记录 ||
	|| 删除 || Delete	|| 一条 SQL 删除一条记录 ||
	|| 更新 || Update	|| 一条 SQL 更新一条或者多条记录 ||
	|| 获取 || Fetch	|| 一条 SQL 获取一条记录 ||
	|| 查询 || Query	|| 一条 SQL 根据条件获取多条记录 ||
	|| 清除 || Clear	|| 一条 SQL 根据条件删除多条记录	||
	|| 建表 || Create	|| 根据实体建表	||
	|| 删表 || Drop	|| 根据实体/表名称进行删表	||
	|| 聚合 || Func   || 执行sum,count等操作   ||
	
	{#FF0000;*请注意：} 这里我是说 “{/一条}”  SQL。 如果通过 Dao 接口，你传入的是一个集合或者数组，它会为每一个元素
	都生成一条 SQL 并执行，并更新操作:
	{{{<java>
	Pet[] pets = xxxx;
	dao.update(pets);	// 可以是数组，当然 pets 也可以是集合
	}}}
	同理，delete 和 insert 也支持传入数组和集合

-----------------------------------------------------------------------------------------------------------------
示例的前提条件
	* 我们假设已经创建了实体类 {*com.zzh.demo.Person} 和实体表 {*t_person}
	* 在文档 [hello.man Nutz.Dao 入门] 中，我们已经声明了这个实体
	* 下述所有的操作都是假设已经有了 dao 变量，并且它指向一个 Dao 的实例。文档 [hello.man Nutz.Dao 入门] 中，\
	我们给出了如何创建 Dao 实例，以及如何搭建运行环境
-----------------------------------------------------------------------------------------------------------------
创建数据表

    为 Pet 创建数据表，如果数据表存在，则自动忽略
    {{{<java>
    //一般我们都这样写
    dao.create(Pet.class, false);
    }}}

-----------------------------------------------------------------------------------------------------------------
删除数据表
    
    删除 Pet 的数据表
    {{{<java>
    dao.drop(Pet.class);//全部删掉哦,没条件的,慎用!!
    }}}

-----------------------------------------------------------------------------------------------------------------
插入 Insert
	{{{<java>
	Person p = new Person();
	p.setName("Peter");
	p.setAge(22);
	dao.insert(p);
	System.out.println(p.getId());
	}}}
	Person 对象的 Id 被自动更新了。
	 * 更多的关于 @Id 注解的描述，请参看 [primary_key.man 关于主键] 以及 [next_prev.man 在插入前后的为字段设值]
-----------------------------------------------------------------------------------------------------------------
取得 Fetch
	根据名称获取 （如果你的实体声明了 @Name 字段, 字符型主键,或者带唯一性索引的字段）
	{{{<java>
	Person p = dao.fetch(Person.class,"Peter");
	System.out.println(p.getId());
	}}}
	根据 ID 获取 （如果你的实体声明了 @Id 字段, 数值型主键）
	{{{<java>
	Person p = dao.fetch(Person.class,2);
	System.out.println(p.getName());
	}}}
	
	@Id和@Name可以同时存在于一个Pojo类内,但不允许标注在同一个属性,毕竟不可以同时是数值型主键又是字符型主键
-----------------------------------------------------------------------------------------------------------------
更新 Update
	{{{<java>
	Person p = dao.fetch(Person.class,2);
	p.setAge(32);
	dao.update(p)
	
	dao.update(p, "^age$"); //仅更新age,参数是个正则表达式
	// 注意, p至少带@Id/@Name/@Pk中的一种
	
	dao.update(list, "^age$"); //更新一个集合也是可以的
	}}}
-----------------------------------------------------------------------------------------------------------------
更新多条
    {{{<java>
    // 根据特定条件更新特定字段
    dao.update(Person.class, Chain.make("dead",true), Cnd.where("age",">",150));
    // 常用的+1更新
    dao.update(Person.class, Chain.makeSpecial("age", "+1").and("location", "yvr"), Cnd.where("name","=", "wendal"));
    }}}
-----------------------------------------------------------------------------------------------------------------
删除 Delete
	直接删对象
	{{{<JAVA>
	dao.delete(pet); // Pet必须带@Id/@Name/@Pk中的一种或多种
	}}}
	根据名称删除 （如果你的实体声明了 @Name 字段）. 批量删除请用clear
	{{{<java>
	dao.delete(Person.class,"Peter");
	}}}
	根据 ID 删除 （如果你的实体声明了 @Id 字段）
	{{{<java>
	dao.delete(Person.class,2);
	}}}
	直接删列表. 如果要按条件删,用dao.clear
	{{{<java>
	dao.delete(list);
	}}}

-----------------------------------------------------------------------------------------------------------------
查询 Query
	查询全部记录
		{{{<java>
		List<Person> people = dao.query(Person.class, null);
		}}}
	按条件查询
		{{{<java>
		List<Person> people = dao.query(Person.class, Cnd.where("name", "like", "P%"));
		}}}
		* Cnd 类的全名是 org.nutz.dao.Cnd
			* 它主要是用来快速替你建立一个 org.nutz.dao.Condition 接口的实现类
			* where() 函数 第一个参数是字段名，要和 Java 类里面的字段名相同。
			* where() 函数 第二个参数遵循 SQL 的标准，可以是 `>`, `<`, `>=`, `<=` 等等
			* 提供了一个 wrap 函数，你可以直接写 SQL 的条件
		* 如果你愿意，你完全可以自己实现一个 Condition，来做更复杂灵活的判断
		* 关于更多的查询条件的说明，请参看 [condition.man 复杂条件]

	分页查询
		{{{<java>
		List<Person> people = dao.query(Person.class, Cnd.where("age", ">", 18), dao.createPager(2, 4));
		}}}
		* dao.createPager 第一个参数是第几页，第二参数是一页有多少条记录
		* 关于分页更多的说明，请参看 [pager.man 分页查询]

-----------------------------------------------------------------------------------------------------------------
清除 Clear
	清除所有记录
		{{{<java>
		dao.clear(Person.class); //还是那句,慎用
		}}}
	按条件清除
		{{{<java>
		dao.clear(Person.class,Cnd.where("id", ">", 35));
		}}}
		* 关于更多的清除条件的说明，请参看 [condition.man 复杂条件]
-----------------------------------------------------------------------------------------------------------------
插入和更新集合
	无论是插入 (Insert) 还是更新 (Update)，你传入的对象都可以不仅仅是一个 POJO，你可以传入：
	 * 集合 `( Collection<?> )`
	 * `Map<?,?>`
	 * 数组 `( T[] )`
	Nutz.Dao 会自动替你拆包，对集合成员依次执行相应操作。 对于 Map，它会迭代每一个值。
	
----------------------------------------------------------------------------------------------------------------
集合操作(func)

	整数类型. 例如调用sum
	
		{{{<JAVA>
		dao.func(Person.class, "sum", "age");
		}}}
	
	其他类型
	
		{{{<JAVA>
		dao.func2(Person.class, "min", "price");
		}}}

----------------------------------------------------------------------------------------------------------------
自动建表

	Dao接口有一个create方法,通过它可以让nutz为你建好数据库表
	
	{{{
	dao.create(Pet.class, false);
	}}}

	第一个参数是Pojo类, 第二个参数是如果表存在,是不是先删再重新建,否则就是保持原样
	
	字段的详细定义,例如定义长度
	
	{{{
	@ColDefine(width=1024)
	private String data;
	}}}
	
	强制自定义字段类型
	
	{{{
	@ColDefine(customType="TEXT", type=ColType.VARCHAR)
	private String fu;
	}}}
	
	添加索引, 类级注解
	{{{
	@TableIndexes({@Index(name="orderid_userid", fields={"orderId", "userId"})})
	public class UserOrder {
	
		private long id;
		private long orderId;
		private long userId;
		//... 其他属性
	}
	}}}
	
	局限性
		* 不生成外键,我们也不推荐用外键
		* 只能解决一般建表需求,复制的表结构请通过自定义sql完成
	
----------------------------------------------------------------------------------------------------------------
批量建表,扫描某个package下的bean,为带@Table注解的类建表
	
	{{{<JAVA>
	Daos.createTablesInPackage(dao, "net.wendal.nutzbook.bean", false);
	}}}
	
----------------------------------------------------------------------------------------------------------------
表结构自动迁移

	{{{<JAVA>
	// 单个迁移
	Daos.migration(dao, User.class, true, false, false); // 新增字段true,删除字段false,检查索引false
	
	// 批量迁移
	Daos.migration(dao, "net.wendal.nutzbook.bean", true, false, false);
	}}}

